﻿//函数说明:
//除getStage外,private函数遵从以下格式:
//使用while(!reader.atEnd()){reader.readNext();...历遍,如果走出循环,抛出错误
//内部if(reader.isStartElement())可以包含多种内部数据
//内部else if(reader.isEndElement() && (reader.name() == "..."))仅判断当前类型
//遵从以上规则的函数中,除getPerformer返回指针外,均返回实例

#include "GenerateR.h"
#include <QDebug>
#include "Single.h"
#include "Ball.h"
#include "OtherSingle.h"
#include "ObjType.h"

GenerateR::GenerateR(){}

GenerateR::~GenerateR(){}

QList<QString> GenerateR::getStageList()
{
    //*
    QFile index_file(":/xml/Index.xml");
    /*/
    QFile index_file("Index.xml");
    //*/
    if(!index_file.open(QIODevice::ReadOnly))//QFile::ReadOnly | QFile::Text))
    {
        qDebug() << "Open file failed.";
        throw "Open file failed.";
    }
    reader.setDevice(&index_file);

    QList<QString> stage_list;

    while(!reader.atEnd())
    {
        reader.readNext();
        if(reader.isStartElement() && reader.name() == "Path")
        {
            stage_list.append(reader.readElementText());
        }
    }
    return stage_list;
}

QList<Performer*> GenerateR::getStage(const QString &stage_file)
{
    QFile file(stage_file);
    if(!file.open(QIODevice::ReadOnly))//QFile::ReadOnly | QFile::Text))
    {
        qDebug() << "No this stage file.";
        throw "No this stage file.";
    }
    reader.setDevice(&file);

    QList<Performer*> performer_list;

    while(!reader.atEnd())
    {
        reader.readNext();
        if(reader.isStartElement())
        {
            if(reader.name() == "Performer")
            {
                performer_list.append(getPerformer(reader.attributes().value("Type").toString()));
            }
        }
        else if(reader.isEndElement() && reader.name() == "Infomation")
        {
            return performer_list;
        }
    }

    qDebug() << "No stage " + stage_file + " in file.";
    throw "No stage " + stage_file + " in file.";
}

Performer * GenerateR::getPerformer(const QString &performer_name)
{
    QString name;
    VPoint site;
    Shape shape;

    while(!reader.atEnd())
    {
        reader.readNext();
        if(reader.isStartElement())
        {
            if(reader.name() == "NickName")
            {
                name = reader.readElementText();
            }
            else if(reader.name() == "Site")
            {
                site = getSite();
            }
            else if(reader.name() == "Shape")
            {
                shape = getShape();
            }
        }
        else if(reader.isEndElement() && (reader.name() == "Performer"))
        {
            //*
            Performer *performer = ObjType::getType(performer_name)->createPerformer(name, site, shape);
            return performer;
            /*/
            if(performer_name == "Single")
            {
                if(name == "Ball")
                {
                    Single *single = new Ball(name, site, shape);
                    return single;
                }
                else
                {
                    Single *single = new OtherSingle(name, site, shape);
                    return single;
                }
            }
            //*/
        }
    }

    qDebug() << "Error in Performer:" + performer_name + ".";
    throw "Error in Performer:" + performer_name + ".";
}

VPoint GenerateR::getSite()
{
    /*读取
     * VPoint site
     */
    VPoint *point = ObjType::getPara()->createVPoint(0, 0);

    while(!reader.atEnd())
    {
        reader.readNext();
        if(reader.isStartElement())
        {
            if(reader.name() == "VPoint")
            {
                *point = getVPoint();
            }
        }
        else if(reader.isEndElement() && (reader.name() == "Site"))
        {
            return *point;
        }
    }

    qDebug() << "Error in Site.";
    throw "Error in Site.";
}

Shape GenerateR::getShape()
{
    /* 读取
     * QVector<VPoint> points
     * double radius
     */
    QList<VPoint> points;
    double radius;

    while(!reader.atEnd())
    {
        reader.readNext();
        if(reader.isStartElement())
        {
            if(reader.name() == "VPoint")
            {
                points.append(getVPoint());
            }
            else if(reader.name() == "Radius")
            {
                radius = reader.readElementText().toDouble();
            }
        }
        else if(reader.isEndElement() && (reader.name() == "Shape"))
        {
            return *ObjType::getPara()->createShape(points.toVector(), radius);
        }
    }

    qDebug() << "Error in Shape.";
    throw "Error in Shape.";
}

VPoint GenerateR::getVPoint()
{
    /* 读取
     * double X;
     * double Y;
     */
    VPoint *point = ObjType::getPara()->createVPoint(0, 0);

    while(!reader.atEnd())
    {
        reader.readNext();
        if(reader.isStartElement())
        {
            if(reader.name() == "x")
            {
                point->setX(reader.readElementText().toDouble());
            }
            else if(reader.name() == "y")
            {
                point->setY(reader.readElementText().toDouble());
            }
        }
        else if(reader.isEndElement() && (reader.name() == "VPoint"))
        {
            return *point;
        }
    }

    qDebug() << "Error in Point.";
    throw "Error in Point.";
}
